angular.module("todoApp", []).controller("TodoController", ["$scope", function(scope) {
	
	// initialize scope vars
	scope.todos = [];
	scope.donesCount = 0;
	scope.count = 0;
	
	// retrieves the value from the text input and stores it as a new todo item
    scope.addTodo = function() {
		// add to store
		todos.push({ text:scope.todoText });
		// clear the input field
		scope.todoText = "";
    };
	
	// triggers when the checkbox is clicked
	scope.updateTodoState = function (todo) {
		scope.donesCount += todo.done ? 1 : -1;
		// store the new value
		todo.ref.update({done: todo.done});
	};
	
 	// removes all checked todos
    scope.removeDones = function() {
		var oldTodos = scope.todos;
		scope.todos = [];
		angular.forEach(oldTodos, function(todo) {
			// remove checked todos from the store
			todo.done ? todo.ref.remove() : todo.deleted? null : scope.todos.push(todo);
		});
		scope.donesCount = 0;
		scope.count = scope.todos.length;
    };
	
	// Angular's built-in ng-pluralize can't be used as it is not supported on IE8
	scope.pluralize = function (s) {
		return s + " item" + (s === 1 ? "" : "s");
	}

	// using Firebase as the backend for storing the todos
	var firebaseStore = new Firebase("https://todo-cref.firebaseio.com/");
	var todos = firebaseStore.child("todos");
	// in order to update the view after the initial load from the store,
	// or when the store was updated from outside the app,
	// scope.$apply must be called through a timeout to prevent
	// errors when called from within an update cycle.
	var applyTimeout, requestViewUpdate = function() {
		// clear any existing timeout to limit the amount of scope.$apply calls
		clearTimeout(applyTimeout);
		// update the view through a timeout
		applyTimeout = setTimeout(function() {
			scope.$apply();
		}, 10);
	}
	// detect added todos and add them to the model
	todos.on("child_added", function (snapshot) {
		var todo = snapshot.val();
		todo.ref = snapshot.ref();
		todo.name = snapshot.name();
		scope.todos.push(todo);
		if (todo.done) scope.donesCount++;
		scope.count++;
		requestViewUpdate();
	});
	// detect removed todos and remove them from the model
	todos.on("child_removed", function (snapshot) {
		var name = snapshot.name();
		scope.todos.some(function(todo) {
			if (todo.name !== name) return;
			if (todo.done) scope.donesCount--;
			scope.count--;
			// hides removed todos
			return todo.deleted = true;
		});
		requestViewUpdate();
	});
	
  }]);